import { ImageLayout, Pixel } from "../model/v3pro.image.layout";
import { lensProp, view } from "ramda";

/**
 * 列表
 * 1. 用于存储布局
 * 2. 布局包括：发送盒、网口、扫描版、面板
 */
export class ImageLayoutList<T extends ImageLayout> {
  constructor(private __keyField?: keyof T) {
    if (this.__keyField) this.__keyLens = lensProp<T, any>(this.__keyField);
  }

  private readonly __keyLens?: any;

  private readonly __list: T[] = [];
  private readonly __map = new Map<any, T>();

  /**
   * 读取key
   * @param layout
   * @private
   */
  private __getKey(layout: T) {
    if (!this.__keyField) return undefined;
    return view(this.__keyLens, layout);
  }

  /**
   * 添加内容到 map
   * @param layout
   * @private
   */
  private __addToMap(layout: T) {
    if (!this.__keyField) return;
    this.__map.set(this.__getKey(layout), layout);
  }

  /**
   * 添加内容
   * @param layout
   */
  add(layout?: T) {
    if (!layout) return;
    if (this.hasByKey(this.__getKey(layout))) return;
    this.__list.push(layout);
    this.__addToMap(layout);
  }

  /**
   * 通过像素获取布局
   * @param pixel
   */
  getByPixel(pixel: Pixel) {
    for (let i = 0; i < this.__list.length; i++) {
      if (this.__list[i].inLayout(pixel)) return this.__list[i];
    }
  }

  /**
   * 通过index获取
   * @param index
   */
  getByIndex(index: number) {
    return this.__list[index];
  }

  /**
   * 通过key获取
   * @param key
   */
  getByKey(key?: any) {
    if (!key && key !== 0) return undefined;
    return this.__map.get(key);
  }

  /**
   * 是否存在key
   * @param key
   */
  hasByKey(key?: any) {
    if (!key && key !== 0) return false;
    return this.__map.has(key);
  }

  /**
   * 移除
   * @param layout
   */
  remove(layout?: T) {
    if (!layout) return;
    let index = this.__list.indexOf(layout);
    if (index > -1) this.__list.splice(index, 1);
    this.__map.delete(this.__getKey(layout));
  }

  /**
   * 通过index移除
   * @param index
   */
  removeByIndex(index: number) {
    this.__list.splice(index, 1);
  }

  removeByKey(key: any) {
    this.remove(this.__map.get(key));
  }

  /**
   * 遍历
   * @param callback
   */
  forEach(callback: (layout: T) => void) {
    this.__list.forEach(callback);
  }

  /**
   * 获取长度
   */
  length() {
    return this.__list.length;
  }

  /**
   * map
   * @param callback
   */
  map(callback: (layout: T) => void) {
    return this.__list.map(callback);
  }

  /**
   * filter
   * @param callback
   */
  filter(callback: (layout: T) => void) {
    return this.__list.filter(callback);
  }

  /**
   * 通过像素过滤
   * @param pixel
   */
  filterByPixel(pixel: Pixel) {
    return this.__list.filter((layout) => layout.inLayout(pixel));
  }

  /**
   * 通过像素过滤
   * @param pixels
   */
  filterByPixels(pixels: Pixel[]) {
    return this.__list.filter((layout) => pixels.some((pixel) => layout.inLayout(pixel)));
  }

  /**
   * 迭代器
   */
  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        return {
          value: this.__list[index++],
          done: index > this.__list.length,
        };
      },
    };
  }
}
